package com.wxh.concurrent;

/**
 * @ClassName: ThreadExecuteQuestion
 * @Description: 线程的执行问题
 * @Author wxh
 * @Date: 2021/3/18 15:39
 * @Version V1.0.0
 * @Since 1.8
 */
public class ThreadExecuteQuestion {
    public static void main(String[] args) throws InterruptedException {
//        threadJoinOneByOne();
//        threadSleep();
        threadWait();
    }

    /**
     * 线程等待
     * @throws InterruptedException
     */
    private static void threadWait() throws InterruptedException{
        Thread t1 = new Thread(ThreadExecuteQuestion::action, "t1");
        Thread t2 = new Thread(ThreadExecuteQuestion::action, "t2");
        Thread t3 = new Thread(ThreadExecuteQuestion::action, "t3");

        threadStartAndWait(t1);
        threadStartAndWait(t2);
        threadStartAndWait(t3);
    }

    /**
     *  启动和等待线程
     * @param thread
     */
    private static void threadStartAndWait(Thread thread){
        if(Thread.State.NEW.equals(thread.getState())){
            thread.start();
        }
        while (thread.isAlive()){
            // 对象锁
            synchronized (thread){
                try {
                    thread.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    /**
     *  线程循环--休眠
     */
    private static void threadSleep() throws InterruptedException{
        Thread t1 = new Thread(ThreadExecuteQuestion::action, "t1");
        Thread t2 = new Thread(ThreadExecuteQuestion::action, "t2");
        Thread t3 = new Thread(ThreadExecuteQuestion::action, "t3");

        t1.start();
        while (t1.isAlive()){
            Thread.sleep(0);
        }

        t2.start();
        while (t2.isAlive()){
            Thread.sleep(0);
        }

        t3.start();
        while (t3.isAlive()){
            Thread.sleep(0);
        }
    }

    /**
     *  线程循环
     */
    private static void threadLoop() throws InterruptedException{
        Thread t1 = new Thread(ThreadExecuteQuestion::action, "t1");
        Thread t2 = new Thread(ThreadExecuteQuestion::action, "t2");
        Thread t3 = new Thread(ThreadExecuteQuestion::action, "t3");

        t1.start();
        while (t1.isAlive()){
            // 自旋 spin
        }

        t2.start();
        while (t2.isAlive()){
            // 自旋 spin
        }

        t3.start();
        while (t3.isAlive()){
            // 自旋 spin
        }
    }

    /**
     *  使用join一个一个执行
     * @throws InterruptedException
     */
    private static void threadJoinOneByOne() throws InterruptedException{
        Thread t1 = new Thread(ThreadExecuteQuestion::action, "t1");
        Thread t2 = new Thread(ThreadExecuteQuestion::action, "t2");
        Thread t3 = new Thread(ThreadExecuteQuestion::action, "t3");

        // 启动线程，通知线程，并不一定执行
        t1.start();
        // 等待该线程终止
        t1.join();

        t2.start();
        t2.join();

        t3.start();
        t3.join();
    }

    private static void action(){
        System.out.printf("线程[%s], 正在执行 \n", Thread.currentThread().getName());
    }
}
